home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 501-525 / disk_514 / dkbtrace / dump2iff.lzh / ilbmw.c < prev    next >
C/C++ Source or Header  |  1991-06-08  |  5KB  |  178 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMW.C  Support routines for writing ILBM files.            1/23/86
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  6.  * This software is in the public domain.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10. #include "iff/packer.h"
  11. #include "iff/ilbm.h"
  12. #include <graphics/view.h>
  13.  
  14. /*---------- InitBMHdr -------------------------------------------------*/
  15. IFFP InitBMHdr(bmHdr0, bitmap, masking, compression, transparentColor,
  16.         pageWidth, pageHeight)
  17.         BitMapHeader *bmHdr0;  struct BitMap *bitmap;
  18.         WORD masking;        /* Masking */
  19.     WORD compression;    /* Compression */
  20.     WORD transparentColor;    /* UWORD */
  21.     WORD pageWidth, pageHeight;
  22.     {
  23.     register BitMapHeader *bmHdr = bmHdr0;
  24.     register WORD rowBytes = bitmap->BytesPerRow;
  25.  
  26.     bmHdr->w = rowBytes << 3;
  27.     bmHdr->h = bitmap->Rows;
  28.     bmHdr->x = bmHdr->y = 0;    /* Default position is (0,0).*/
  29.     bmHdr->nPlanes = bitmap->Depth;
  30.     bmHdr->masking = masking;
  31.     bmHdr->compression = compression;
  32.     bmHdr->pad1 = 0;
  33.     bmHdr->transparentColor = transparentColor;
  34.     bmHdr->xAspect = bmHdr->yAspect = 1;
  35.     bmHdr->pageWidth = pageWidth;
  36.     bmHdr->pageHeight = pageHeight;
  37.  
  38.     if (pageWidth < 360)
  39.     if (pageHeight < 250) {
  40.            bmHdr->xAspect = x320x200Aspect;
  41.        bmHdr->yAspect = y320x200Aspect;
  42.            }
  43.         else {
  44.            bmHdr->xAspect = x320x400Aspect;
  45.        bmHdr->yAspect = y320x400Aspect;
  46.            }
  47.     else
  48.     if (pageHeight < 250) {
  49.            bmHdr->xAspect = x640x200Aspect;
  50.        bmHdr->yAspect = y640x200Aspect;
  51.            }
  52.     else {
  53.           bmHdr->xAspect = x640x400Aspect;
  54.       bmHdr->yAspect = y640x400Aspect; 
  55.           }
  56.  
  57.     return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY );
  58.     }
  59.  
  60. /*---------- PutCMAP ---------------------------------------------------*/
  61. IFFP PutCMAP(context, vp)
  62.       GroupContext *context;
  63.       struct ViewPort *vp;
  64.    {
  65.    IFFP iffp;
  66.    ColorRegister colorReg;
  67.    int nColorRegs;
  68.    UWORD *CMapEntry;
  69.    struct ColorMap *colorMap;
  70.  
  71.    colorMap = vp->ColorMap;
  72.    nColorRegs = colorMap->Count;
  73.  
  74.    if ((vp->Modes & HIRES) && (nColorRegs > 16))
  75.       nColorRegs = 16;
  76.  
  77.    if ((vp->Modes & HAM) && (nColorRegs > 16))
  78.       nColorRegs = 16;
  79.  
  80.    iffp = PutCkHdr(context, ID_CMAP, nColorRegs * sizeofColorRegister);
  81.    CheckIFFP();
  82.  
  83.    CMapEntry = (UWORD *)colorMap->ColorTable;
  84.  
  85.    for (;  nColorRegs;  --nColorRegs)  {
  86.       colorReg.red   = ( *CMapEntry >> 4 ) & 0xf0;
  87.       colorReg.green = ( *CMapEntry      ) & 0xf0;
  88.       colorReg.blue  = ( *CMapEntry << 4 ) & 0xf0;
  89.       iffp = IFFWriteBytes(context, (BYTE *)&colorReg, sizeofColorRegister);
  90.       CheckIFFP();
  91.       CMapEntry++;
  92.       }
  93.  
  94.    iffp = PutCkEnd(context);
  95.    return(iffp);
  96.    }
  97.  
  98. IFFP PutCAMG(context, mode)
  99.       GroupContext *context;
  100.       LONG mode;   
  101.    {
  102.    IFFP iffp;
  103.    int CAMG_Size = 4;
  104.  
  105.    iffp = PutCkHdr(context, ID_CAMG, 4L);
  106.    CheckIFFP();
  107.  
  108.    iffp = IFFWriteBytes(context, (BYTE *)&mode, CAMG_Size);
  109.    CheckIFFP();
  110.  
  111.    iffp = PutCkEnd(context);
  112.    return(iffp);
  113.    }
  114.  
  115. /*---------- PutBODY ---------------------------------------------------*/
  116. /* NOTE: This implementation could be a LOT faster if it used more of the
  117.  * supplied buffer. It would make far fewer calls to IFFWriteBytes (and
  118.  * therefore to DOS Write). */
  119. IFFP PutBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  120.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  121.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  122.    {         
  123.    IFFP iffp;
  124.    LONG rowBytes = bitmap->BytesPerRow;
  125.    int dstDepth = bmHdr->nPlanes;
  126.    Compression compression = bmHdr->compression;
  127.    int planeCnt;        /* number of bit planes including mask */
  128.    register int iPlane, iRow;
  129.    register LONG packedRowBytes;
  130.    BYTE *buf;
  131.    BYTE *planes[MaxAmDepth + 1]; /* array of ptrs to planes & mask */
  132.  
  133.    if ( bufsize < MaxPackedSize(rowBytes)  ||    /* Must buffer a comprsd row*/
  134.         compression > cmpByteRun1  ||        /* bad arg */
  135.     bitmap->Rows != bmHdr->h   ||        /* inconsistent */
  136.     rowBytes != RowBytes(bmHdr->w)  ||    /* inconsistent*/
  137.     bitmap->Depth < dstDepth   ||        /* inconsistent */
  138.     dstDepth > MaxAmDepth )            /* too many for this routine*/
  139.       return(CLIENT_ERROR);
  140.  
  141.    planeCnt = dstDepth + (mask == NULL ? 0 : 1);
  142.  
  143.    /* Copy the ptrs to bit & mask planes into local array "planes" */
  144.    for (iPlane = 0; iPlane < dstDepth; iPlane++)
  145.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  146.    if (mask != NULL)
  147.       planes[dstDepth] = mask;
  148.  
  149.    /* Write out a BODY chunk header */
  150.    iffp = PutCkHdr(context, ID_BODY, szNotYetKnown);
  151.    CheckIFFP();
  152.  
  153.    /* Write out the BODY contents */
  154.    for (iRow = bmHdr->h; iRow > 0; iRow--)  {
  155.       for (iPlane = 0; iPlane < planeCnt; iPlane++)  {
  156.  
  157.          /* Write next row.*/
  158.          if (compression == cmpNone) {
  159.             iffp = IFFWriteBytes(context, planes[iPlane], rowBytes);
  160.             planes[iPlane] += rowBytes;
  161.             }
  162.  
  163.          /* Compress and write next row.*/
  164.          else {
  165.             buf = buffer;
  166.             packedRowBytes = PackRow(&planes[iPlane], &buf, rowBytes);
  167.             iffp = IFFWriteBytes(context, buffer, packedRowBytes);
  168.             }
  169.  
  170.          CheckIFFP();
  171.          }
  172.       }
  173.  
  174.    /* Finish the chunk */
  175.    iffp = PutCkEnd(context);
  176.    return(iffp);
  177.    }
  178.